#!/usr/bin/python
#-*- coding: UTF-8 -*-
#author: fox
#desc: 封装浏览器的基本操作
#date: 2024/03/23

import logging, logging.config
import time, random
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# TODO: 后续改为全局配置
STEALTH_MIN_JS_PATH = '/Users/fox/Downloads/stealth.min.js'
class BrowserDriver(object):
    # 每一步操作后的等待时间
    sleep_range = [5, 10]

    def __init__(self):
        self.driver = None
        self.logger = logging.getLogger("browser")

    def setup(self, *args):
        try:
            opt = webdriver.ChromeOptions()
            #opt.add_argument('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36')
            for (item_type, value) in args:
                if "argument" == item_type:
                    opt.add_argument(value)
                elif "option" == item_type:
                    opt.add_experimental_option(value[0], value[1])
                elif "extension" == item_type:
                    opt.add_extension(value)
                        
            print(opt)
            self.driver = webdriver.Chrome(options=opt)
            '''
            with open(STEALTH_MIN_JS_PATH, "r") as fp:
                js = fp.read()
                self.driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
                    "source": js
                })
            '''
        except Exception as e:
            self.logger.exception("err=setup_driver args=%s", args)

        return self.driver

    def get_driver(self):
        return self.driver

    '''
        @desc 打开指定页面进行任务操作
        @param url string
        @param items list 抽象的任务列表
            action 取值 send_keys/click
            [
                (By.xxx, selector, action, [content])
                ...
            ]
    '''
    def do_task(self, url, items):
        try:
            start = time.time()
            self.driver.get(url)
            time.sleep(5)

            for index, item in enumerate(items):
                select_type, path_selector, action = item[0:3]

                dom_element = self.driver.find_element(select_type, path_selector)
                if dom_element is None:
                    return False

                wait_second = random.randint(self.sleep_range[0], self.sleep_range[1]) if index > 0 else 0
                self.do_action(dom_element, item, wait_second)

            end = time.time()
            self.logger.info("op=do_task url=%s count=%d cost=%.3f", url, len(items), end-start)
            return True
        except Exception as e:
            self.logger.exception("err=do_task url=%s items=%s", url, items)
            return False

    '''
        @desc 在元素上执行动作
        @param element WebElement
        @param item tuple
        @param wait_second int 延迟时间, 单位为s
        @return 
    '''
    def do_action(self, element, item, wait_second=0):
        try:
            action, content = item[2], item[3] if len(item) >= 4 else None
            if "send_keys" == action:
                if wait_second > 0:
                    WebDriverWait(self.driver, wait_second, 1).until(EC.visibility_of(element))
                element.send_keys(content)
            elif "click" == action:
                if wait_second > 0:
                    WebDriverWait(self.driver, wait_second, 1).until(EC.element_to_be_clickable(element)).click()
                else:
                    element.click()

            self.logger.debug("op=do_action id=%s item=%s wait_second=%d", element.id, item, wait_second)
            return True
        except Exception as e:
            self.logger.exception("err=do_action id=%s item=%s wait=%d", element.id, item, wait_second)
            return False

if __name__ == "__main__":
    logging.config.fileConfig("log.conf")

    options = [
        ("argument", 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'),
        ("extension", '/Users/fox/Downloads/metamask.crx')
    ]

    browser = BrowserDriver()
    driver = browser.setup(*options)
    print(driver)

    browser.do_task("https://paramgaming.com/", [
        (By.XPATH, '/html/body/div[1]/header/nav/div/div[2]/div/a/button/span', "click"),
        (By.XPATH, '//*[@id="email"]', "send_keys", "xxxxx"),
        (By.XPATH, '//*[@id="password"]', "send_keys", "xxxxxx"),
        (By.XPATH, '/html/body/div[1]/main/div/div[3]/div/form/div[3]/button/span', "click"),
    ])

    time.sleep(60)